
package com.xijia.example.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xijia.example.conut.RobotUserConst;
import com.xijia.example.enums.SiteToolDic;
import com.xijia.example.manage.all.model.entity.Site;
import com.xijia.example.manage.all.model.entity.SiteCheckLog;
import com.xijia.example.manage.all.model.vo.SiteVO;
import com.xijia.example.manage.all.service.SiteCheckLogService;
import com.xijia.example.manage.all.service.SiteService;
import io.github.wslxm.springbootplus2.core.utils.date.XjLocalDateTimeUtil;
import io.github.wslxm.springbootplus2.manage.sys.model.entity.SysConfig;
import io.github.wslxm.springbootplus2.manage.sys.model.vo.SysConfigVO;
import io.github.wslxm.springbootplus2.manage.sys.service.SysConfigService;
import io.github.wslxm.springbootplus2.starter.robot.service.RobotService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 站点异常通知  (每 5分钟执行一次)
 *
 * @author wangsong
 * @date 2023/06/15
 */
@Configuration
@EnableScheduling
@Slf4j
public class SiteErrorNotifyTask {

    @Autowired
    private SiteService siteService;
    @Autowired
    private SiteCheckLogService siteCheckLogService;

    @Autowired
    private RobotService robotService;

    @Autowired
    private SysConfigService sysConfigService;


    @Scheduled(cron = "0 0/5 * * * ?")
//    @Scheduled(cron = "0/20 * * * * ?")
    public void run() {
        this.siteStateErrorNotify();
        this.certExpirationNotify();
    }


    /**
     * 站点状态异常通知
     */
    private void siteStateErrorNotify() {
        List<Site> list = siteService.list(new LambdaQueryWrapper<Site>()
                .eq(Site::getVisitState, SiteToolDic.VisitState.ERROR));
        if (list.size() == 0) {
            return;
        }
        // 当前系统的所有站点检查
        StringBuilder siteErrorList = new StringBuilder();
        for (Site site : list) {
            // 1、再次检查是否正常, 会叠加检查异常日志, 连续达到 N 次异常推送异常信息
            boolean isNormal = siteService.siteChecks(site.getId());
            if (isNormal) {
                continue;
            }
            // 2、检查是否已经连续到达6次检查异常
            List<SiteCheckLog> siteCheckLogList = siteCheckLogService.list(new LambdaQueryWrapper<SiteCheckLog>()
                    .orderByDesc(SiteCheckLog::getCreateTime)
                    .eq(SiteCheckLog::getSiteId, site.getId())
                    .last(" limit 3")
            );
            List<SiteCheckLog> successList = siteCheckLogList.stream().filter(p -> p.getState().equals(SiteToolDic.VisitState.NORMAL.getValue())).collect(Collectors.toList());
            if (successList.size() > 0) {
                return;
            }

            siteErrorList.append("\n").append(site.getSite()).append(" | ").append(site.getLastCheckLog());
        }
        if (StringUtils.isNotBlank(siteErrorList.toString())) {
            String errorNotifyMsg = "发现异常站点, 请及时处理" + siteErrorList + "\n通知时间" + XjLocalDateTimeUtil.parse(LocalDateTime.now());
            robotService.sendMsg("【站点工具中心】" + errorNotifyMsg, RobotUserConst.USER_WS);
        }
    }


    /**
     * 证书到期监听
     *
     * @return void
     * @date 2024/9/26 9:25
     */
    private void certExpirationNotify() {
        List<Site> list = siteService.list(new LambdaQueryWrapper<Site>().isNotNull(Site::getHttpsExpirationTime));
        if (list.size() == 0) {
            return;
        }
        // 获取配置 证书有效期低于多少天通知
        SysConfigVO config = sysConfigService.findByCode("cert-notify-le-day-num");
        int leDayNum = Integer.parseInt(config.getContent());

        StringBuilder siteErrorList = new StringBuilder();
        for (Site site : list) {
            if (site.getHttpsExpirationTime() == null) {
                continue;
            }
            long dayNum = XjLocalDateTimeUtil.betweenTwoTime(LocalDateTime.now(), site.getHttpsExpirationTime(), ChronoUnit.DAYS);
            // 在次检查
            if (dayNum < leDayNum) {
                siteService.siteChecks(site.getId());
                site = siteService.getById(site.getId());
            }
            dayNum = XjLocalDateTimeUtil.betweenTwoTime(LocalDateTime.now(), site.getHttpsExpirationTime(), ChronoUnit.DAYS);
            if (dayNum < leDayNum) {
                siteErrorList.append("\n").append(site.getSite()).append(" | 到期时间: ").append(XjLocalDateTimeUtil.parse(site.getHttpsExpirationTime())).append(" | 剩余: ").append(dayNum).append("天");
            }
        }
        // 有快到期的就进行通知
        if (StringUtils.isNotBlank(siteErrorList.toString())) {
            String notifyMsg = "发现有 https 证书即将到期 请及时处理" + siteErrorList + "\n通知时间" + XjLocalDateTimeUtil.parse(LocalDateTime.now());
            robotService.sendMsg("【站点工具中心】" + notifyMsg, RobotUserConst.USER_WS);
        }
    }
}
